/**
 * 认证工具模块
 * 
 * 本模块作为系统认证功能的统一入口点，提供简洁的身份验证和令牌管理功能。
 * 参考Vue项目的简洁实现方式，避免复杂的结构和多层嵌套。
 * 
 * 主要功能：
 * - 用户身份验证与会话管理
 * - token的获取、设置与刷新
 * - 用户信息和权限管理
 * - 部门隔离和数据过滤
 * - 角色与权限验证
 */
import axios, { AxiosError } from 'axios';
import { message } from 'antd';
import { News, User } from '../types';
import { STORAGE_KEYS, ROLE_TYPES, MESSAGES } from '../constants/common';

// 声明一个函数类型，用于延迟加载store
type DispatchFunction = (action: { type: string; payload?: any }) => void;
let storeDispatch: DispatchFunction | null = null;

// 设置dispatch函数的方法，由store模块调用
export const setDispatch = (dispatch: DispatchFunction): void => {
  storeDispatch = dispatch;
};

/**
 * 认证工具类
 */
class Auth {
  /**
   * 获取Token
   */
  getToken(): string | null {
    return localStorage.getItem(STORAGE_KEYS.TOKEN);
  }

  /**
   * 设置Token
   */
  setToken(token: string): void {
    // 确保token格式正确
    if (token && !token.startsWith('Bearer ')) {
      token = `Bearer ${token}`;
    }
    localStorage.setItem(STORAGE_KEYS.TOKEN, token);
  }

  /**
   * 移除Token
   */
  removeToken(): void {
    localStorage.removeItem(STORAGE_KEYS.TOKEN);
  }

  /**
   * 获取用户信息
   */
  getUserInfo(): User | null {
    const userInfoStr = localStorage.getItem(STORAGE_KEYS.USER_INFO);
    if (!userInfoStr) return null;
    try {
      return JSON.parse(userInfoStr);
    } catch (err) {
      console.error('解析用户信息失败:', err);
      return null;
    }
  }

  /**
   * 设置用户信息
   */
  setUserInfo(userInfo: User): void {
    // 确保保存完整的用户信息，包含个人中心表单需要的所有字段
    const completeUserInfo = {
      ...userInfo,
      email: userInfo.email || '',
      phone: userInfo.phone || '',
      location: userInfo.location || '',
      introduction: userInfo.introduction || '',
      gender: userInfo.gender !== undefined ? userInfo.gender : 0,
      region: userInfo.region || '',
    };
    
    localStorage.setItem(STORAGE_KEYS.USER_INFO, JSON.stringify(completeUserInfo));
    
    // 使用setTimeout避免在reducer执行期间调用store.getState()
    if (storeDispatch !== null) {
      const dispatch = storeDispatch; // 复制引用避免setTimeout内为null
      setTimeout(() => {
        try {
          dispatch({ type: 'user/setUser', payload: completeUserInfo });
        } catch (error) {
          console.error('Redux状态更新失败:', error);
        }
      }, 0);
    }
    
    // 如果用户信息中包含权限，也保存权限
    if (userInfo.role?.rights) {
      this.setUserRights(userInfo.role.rights);
    }
  }

  /**
   * 获取用户权限
   */
  getUserRights(): string[] {
    const rightsStr = localStorage.getItem(STORAGE_KEYS.USER_RIGHTS);
    if (!rightsStr) return [];
    try {
      return JSON.parse(rightsStr);
    } catch (err) {
      console.error('解析用户权限失败:', err);
      return [];
    }
  }

  /**
   * 设置用户权限
   */
  setUserRights(rights: string[]): void {
    localStorage.setItem(STORAGE_KEYS.USER_RIGHTS, JSON.stringify(rights));
  }

  /**
   * 清除用户信息和Token
   */
  clearUserInfo(): void {
    localStorage.removeItem(STORAGE_KEYS.TOKEN);
    localStorage.removeItem(STORAGE_KEYS.USER_INFO);
    localStorage.removeItem(STORAGE_KEYS.USER_RIGHTS);
    
    // 如果storeDispatch可用，清除Redux状态
    if (storeDispatch) {
      storeDispatch({ type: 'user/clearUser' });
    }
  }

  /**
   * 检查是否已登录
   */
  isAuthenticated(): boolean {
    const token = this.getToken();
    const userInfo = this.getUserInfo();
    const isAuth = !!token && !!userInfo;
    
    // 仅在开发环境输出日志
    if (process.env.NODE_ENV === 'development') {
    console.log('认证检查:', {
      tokenExists: !!token,
      userInfoExists: !!userInfo,
      isAuthenticated: isAuth
    });
    }
    
    return isAuth;
  }

  /**
   * 检查用户是否拥有某项权限
   * @param permissionKey 权限键名
   */
  hasPermission(permissionKey: string): boolean {
    const userInfo = this.getUserInfo();
    
    // 如果没有用户信息，无权限
    if (!userInfo) {
      console.log('[权限检查] 无用户信息，权限检查失败:', permissionKey);
      return false;
    }
    
    // 如果是超级管理员，拥有所有权限
    if (userInfo.role?.roleType === ROLE_TYPES.SUPER_ADMIN || 
        userInfo.roleId === '1' || 
        userInfo.roleId === 1) {
      console.log('[权限检查] 超级管理员权限自动通过:', permissionKey);
      return true;
    }
    
    // 从本地缓存获取权限，避免重复获取
    const rights = this.getUserRights();
    
    // 检查是否有指定权限
    return rights.includes(permissionKey);
  }

  /**
   * 退出登录
   */
  logout(): void {
    this.clearUserInfo();
    // 可在此处添加其他登出逻辑，如重定向等
    window.location.href = '/login';
  }

  /**
   * 刷新令牌
   */
  async refreshToken(): Promise<boolean> {
    try {
      const response = await axios.post('/adminapi/user/refresh-token');
      if (response.data && response.data.token) {
        this.setToken(response.data.token);
        return true;
      }
      return false;
    } catch (error) {
      console.error('刷新令牌失败:', error);
      return false;
    }
  }
  
  /**
   * 验证令牌
   */
  async validateToken(): Promise<boolean> {
    const token = this.getToken();
    
    if (!token) {
      return false;
    }
    
    try {
      const response = await axios.post('/adminapi/user/validate-token');
      return response.status === 200;
    } catch (error) {
      console.error('验证令牌失败:', error);
      // 如果是401错误，则清除用户信息并提示重新登录
      const axiosError = error as AxiosError;
      if (axiosError.response?.status === 401) {
        this.clearUserInfo();
        message.warning(MESSAGES.AUTH.SESSION_EXPIRED);
      }
      return false;
    }
  }
  
  /**
   * 处理登出逻辑
   */
  handleLogout(): void {
    this.logout();
  }
  
  /**
   * 尝试刷新token
   */
  async tryRefreshToken(): Promise<boolean> {
    return this.refreshToken();
  }
  
  /**
   * 获取用户名
   * @returns 当前用户名
   */
  getUsername(): string {
    const user = this.getUserInfo();
    return user?.username || '';
  }
  
  /**
   * 获取用户所在区域
   * @returns 用户区域
   */
  getUserRegion(): string {
    const user = this.getUserInfo();
    return user?.region || '';
  }
  
  /**
   * 判断是否为超级管理员(roleId === 1)
   * @returns 是否是超级管理员
   */
  isSuperAdmin(): boolean {
    const user = this.getUserInfo();
    return (user?.role?.id === '1' || 
           user?.role?.id === 1 ||
           user?.role?.roleType === ROLE_TYPES.SUPER_ADMIN || 
           user?.role?.roleName === '超级管理员');
  }
  
  /**
   * 判断是否为区域管理员(roleId === 2)
   * @returns 是否是区域管理员
   */
  isRegionAdmin(): boolean {
    const user = this.getUserInfo();
    return (user?.role?.id === '2' || 
           user?.role?.id === 2 ||
           user?.role?.roleType === ROLE_TYPES.ADMIN);
  }
  
  /**
   * 判断是否为普通编辑(roleId === 3)
   * @returns 是否是普通编辑
   */
  isEditor(): boolean {
    const user = this.getUserInfo();
    return (user?.role?.id === '3' || 
           user?.role?.id === 3 ||
           user?.role?.roleType === ROLE_TYPES.EDITOR);
  }
  
  /**
   * 能否访问指定区域的内容
   * 超级管理员可以访问所有区域
   * 区域管理员只能访问自己的区域
   * 编辑只能访问自己的区域
   * @param region 区域标识
   * @returns 是否可以访问该区域
   */
  canAccessRegion(region: string): boolean {
    const user = this.getUserInfo();
    
    // 没有用户信息，无权限
    if (!user) {
      return false;
    }
    
    // 超级管理员可以访问所有区域
    if (this.isSuperAdmin()) {
      return true;
    }
    
    // 如果目标区域是全球，所有角色可以访问
    if (region === 'global' || region === '' || !region) {
      return true;
    }
    
    // 区域管理员和编辑只能访问自己的区域
    const userRegion = user.region || '';
    return userRegion === region;
  }
  
  /**
   * 能否管理指定作者的内容
   * 超级管理员可以管理所有人的内容
   * 区域管理员只能管理自己区域的内容
   * 普通编辑只能管理自己的内容
   * @param authorName 作者用户名
   * @returns 是否可以管理该作者的内容
   */
  canManageAuthor(authorName: string): boolean {
    const user = this.getUserInfo();
    
    // 没有用户信息，无权限
    if (!user) {
      return false;
    }
    
    // 超级管理员可以管理所有作者
    if (this.isSuperAdmin()) {
      return true;
    }
    
    // 如果是自己创建的内容，可以管理
    if (user.username === authorName) {
      return true;
    }
    
    // 区域管理员可以管理同区域的所有作者
    // 此处需要通过API检查作者是否在同一区域，简化处理，暂时只返回false
    if (this.isRegionAdmin()) {
      // 实际应用中，此处需要通过API查询作者所在区域，然后比较
      return false;
    }
    
    // 普通编辑不能管理其他人的内容
    return false;
  }
  
  /**
   * 根据部门过滤用户列表
   * 超级管理员可以查看所有用户
   * 区域管理员只能查看自己区域的用户
   * @param userList 用户列表
   * @returns 过滤后的用户列表
   */
  filterUsersByDepartment(userList: User[]): User[] {
    const currentUser = this.getUserInfo();
    
    // 如果没有当前用户信息，无权限查看任何人
    if (!currentUser) {
      return [];
    }
    
    // 超级管理员可以查看所有用户
    if (this.isSuperAdmin()) {
      return userList;
    }
    
    // 区域管理员只能查看自己区域的用户
    if (this.isRegionAdmin()) {
      return userList.filter(user => {
        // 可以查看自己
        if (user.username === currentUser.username) {
          return true;
        }
        
        // 可以查看同区域的用户
        const userRegion = user.region || '';
        const currentRegion = currentUser.region || '';
        return userRegion === currentRegion;
      });
    }
    
    // 普通编辑只能查看自己
    return userList.filter(user => user.username === currentUser.username);
  }
  
  /**
   * 根据部门过滤新闻列表
   * 超级管理员可以查看所有新闻
   * 区域管理员只能查看自己区域的新闻
   * 普通编辑只能查看自己创建的新闻
   * @param newsList 新闻列表
   * @returns 过滤后的新闻列表
   */
  filterNewsByDepartment(newsList: News[]): News[] {
    const currentUser = this.getUserInfo();
    
    // 如果没有当前用户信息，无权限查看任何新闻
    if (!currentUser) {
      return [];
    }
    
    // 超级管理员可以查看所有新闻
    if (this.isSuperAdmin()) {
      return newsList;
    }
    
    // 区域管理员可以查看自己区域的新闻
    if (this.isRegionAdmin()) {
      return newsList.filter(news => {
        // 可以查看自己创建的新闻
        if (news.author === currentUser.username) {
          return true;
        }
        
        // 可以查看同区域的新闻
        const newsRegion = typeof news.region === 'object' ? 
          String(news.region.value || news.region.id) : 
          String(news.region || '');
          
        const currentRegion = currentUser.region || '';
        return newsRegion === currentRegion || newsRegion === '' || newsRegion === 'global';
      });
    }
    
    // 普通编辑只能查看自己创建的新闻
    return newsList.filter(news => news.author === currentUser.username);
  }
}

// 创建单例实例
const auth = new Auth();

export default auth;

/**
 * 获取默认权限列表
 * 基于角色ID返回预设的权限数组
 * 
 * @param roleId 角色ID (1=超管, 2=管理员, 3=编辑)
 * @returns 该角色拥有的默认权限路径数组
 */
export const getDefaultRights = (roleId: number): string[] => {
  const rights: string[] = [];
  
  // 根据角色ID设置默认权限
  switch (roleId) {
    case 1: // 超级管理员
      rights.push('admin');
      rights.push('admin/user/list');
      rights.push('admin/user/add');
      rights.push('admin/user/edit');
      rights.push('admin/user/delete');
      rights.push('admin/role/list');
      rights.push('admin/role/add');
      rights.push('admin/role/edit');
      rights.push('admin/role/delete');
      rights.push('admin/news/list');
      rights.push('admin/news/add');
      rights.push('admin/news/edit');
      rights.push('admin/news/delete');
      rights.push('admin/news/publish');
      rights.push('admin/news/unpublish');
      rights.push('admin/news/audit');
      rights.push('admin/system/settings');
      break;
    case 2: // 管理员
      rights.push('admin');
      rights.push('admin/news/list');
      rights.push('admin/news/add');
      rights.push('admin/news/edit');
      rights.push('admin/news/delete');
      rights.push('admin/news/publish');
      rights.push('admin/news/unpublish');
      rights.push('admin/news/audit');
      break;
    case 3: // 编辑
      rights.push('admin');
      rights.push('admin/news/list');
      rights.push('admin/news/add');
      rights.push('admin/news/edit');
      break;
    default:
      // 默认无权限
      break;
  }
  
  return rights;
}; 